<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    
    <title>Java NIO 笔记04 | Huhailong</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    
        <meta property="algolia:search" data-application-id="Z2O8U9ACCM" data-api-key="e2ecf104500495239b45a6d38163c2e8" data-index-name="huhailong">
    

    

    

    
        <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>😃</text></svg>">
    

    
    <link rel="stylesheet" href="https://unpkg.com/gitalk/dist/gitalk.css">
    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1630473019367.css">

    <script src="https://use.fontawesome.com/0807d6e1ca.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            gitalk: {
                enable: true,
                clientID: "de841f92787224d0163e",
                clientSecret: "2b8243d84acb67269b200a14fa12ed5d5a33c5b4",
                repo: "blog-message",
                owner: "huhailonggit",
                admin: ["huhailonggit",],
                distractionFreeMode: true  // Facebook-like distraction free mode
            },
            
            
            
        }
        window.aomori_logo_typed_animated = true
        window.aomori_search_algolia = true

    </script>

<meta name="generator" content="Hexo 5.4.0"></head>

<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-avatar avatar avatar-sm">
                <img src="/images/avatar.jpg" alt="胡海龙">
            </div>
            
            <div class="header-type-inner">
                
                    <div id="typed-strings" style="display:none">
                        <p>Huhailong</p>
                    </div>
                    <a class="header-type-title" id="typed" href="/"></a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
                <a href="/">Home</a>
                
                <a href="/archives">Archives</a>
                
                <a href="/friends">Links</a>
                
                <a href="/photography">Photography</a>
                
            </div>
            <div class="header-menu-social">
                
    <a class="social" target="_blank" href="https://gitee.com/hlovez">
        <box-icon type='' name='code-alt'></box-icon>
    </a>

    <a class="social" target="_blank" href="https://www.huhailong.vip">
        <box-icon type='' name='home'></box-icon>
    </a>

            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                    <a href="/">Home</a>
                    
                    <a href="/archives">Archives</a>
                    
                    <a href="/friends">Links</a>
                    
                    <a href="/photography">Photography</a>
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckv6sgcs90000r4uk7uuxh9g5" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      Java NIO 笔记04
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2021-10-25T15:01:47.683Z" itemprop="datePublished">2021-10-25</time>
</div>

            

            
            <div class="article-tag">
                <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java-NIO/" rel="tag">Java NIO</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/%E7%AC%94%E8%AE%B0/" rel="tag">笔记</a></li></ul>
            </div>
            
        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <h3 id="Java-NIO-中Channel与Channel的传输"><a href="#Java-NIO-中Channel与Channel的传输" class="headerlink" title="Java NIO 中Channel与Channel的传输"></a>Java NIO 中Channel与Channel的传输</h3><ul>
<li>transferFrom()</li>
<li>transferTo()</li>
</ul>
<p>在 Java NIO 中，如果其中一个Channel为FileChannel，那么您可以将数据直接从一个通道传输到另一个通道，FileChannel类中有一个transferTo()和一个transferFrom()方法，可以为我们执行这样的操作。</p>
<h4 id="transferFrom"><a href="#transferFrom" class="headerlink" title="transferFrom()"></a>transferFrom()</h4><p>FileChannel.tranferFrom()方法将数据从源通道传输到FileChannel，例如下面这样：</p>
<span id="more"></span>

<pre><code class="java">RandomAccessFile fromFile = new RandomAccessFile(&quot;fromFile.txt&quot;,&quot;rw&quot;);
FileChannel fromChannel = fromFile.getChannel();
RandomAccessFile toFile = new RandomAccessFile(&quot;toFile.txt&quot;,&quot;rs&quot;);
FileChannel toChannel = toFile.getChannel();
long position = 0;
long count = fromChannel.size();
toChannel.transferFrom(fromChannel,position,count);
</code></pre>
<p>参数含义：</p>
<ul>
<li>fromChannel：源文件Channel</li>
<li>position: 从源文件的那个索引位置开始写入</li>
<li>count：传输多少字节</li>
</ul>
<h4 id="transferTo"><a href="#transferTo" class="headerlink" title="transferTo()"></a>transferTo()</h4><p>transferTo()方法时从FileChannel传输数据到其他的通道。例如：</p>
<pre><code class="java">RandomAccessFile fromFile = new RandomAccessFile(&quot;fromFile.txt&quot;,&quot;rw&quot;);
FileChannel fromChannel = fromFile.getChannel();
RandomAccessFile toFile = new RandomAccessFile(&quot;toFile.txt&quot;,&quot;rw&quot;);
FileChannel toChannel = toFile.getChannel();
long position = 0;
long count = fromChannel.size();
fromChannel.transferTo(position,count,toChannel);
</code></pre>
<p><em>注意：一些SoocketChannel实现可能只传输SocketChannel在其内部缓冲区准备好的数据，及时SocketChannel稍后可能有更多的可用数据。</em></p>
<h3 id="Java-NIO-Selector"><a href="#Java-NIO-Selector" class="headerlink" title="Java NIO Selector"></a>Java NIO Selector</h3><p>Java NIO Selector 是一个组件，它可以检查一个或多个Java NIO Channel实例，并确定那些Channel准备好用于例如读取或写入的操作。通过这种方式，单个线程可以管理多个通道，从而管理多个网络连接。</p>
<h4 id="为什么选择使用Selector？"><a href="#为什么选择使用Selector？" class="headerlink" title="为什么选择使用Selector？"></a>为什么选择使用Selector？</h4><p>它的优点是我们可以使用更少的线程来处理多个通道。事实上我们可以只使用一个线程来处理我们所有的Channel，因为线程也占用操作系统中的一些资源（内存），所以线程之间的切换对于操作系统来说是昂贵的。因此，我们使用的线程越少越好。（当然了，如今的CPU性能越来越好，如果是多核CPU，多线程更能是CPU发挥作用）</p>
<p>下面是一个单线程使用Selector来处理三个Channel的示意图：</p>
<p><img src="https://img-blog.csdnimg.cn/img_convert/4cd77218976af75d2e5b00a01392385e.png" alt="selector1"></p>
<h4 id="创建一个Selector"><a href="#创建一个Selector" class="headerlink" title="创建一个Selector"></a>创建一个Selector</h4><p>我们可以通过调用Selector.open()方法来创建一个selector，像下面这样：</p>
<pre><code class="java">Selector selector = Selector.open();
</code></pre>
<h4 id="将Channel注册到Selector"><a href="#将Channel注册到Selector" class="headerlink" title="将Channel注册到Selector"></a>将Channel注册到Selector</h4><p>为了使用Selector来处理通道，我们必须向Selector注入要处理的Channel，我们可以使用SelectableChannel.register()方法注入，像下面这样：</p>
<pre><code class="java">channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
</code></pre>
<p>注意，Channel必须处于非阻塞模式下才能与Selector一起使用，__这意味着我们不能将FileChannel与Selector一起使用，因为FileChannel无法切换到非阻塞模式__。不过，SocketChannel可以正常工作。</p>
<p>注意register方法的第二个参数，它是一个“关注集”，意思是您关注Channel收到那些事件。通过Selector，我们可以监听四种不同的事件：</p>
<ol>
<li>Connect</li>
<li>Accept</li>
<li>Read</li>
<li>Write</li>
</ol>
<p>“触发事件”的通道也被称为“准备好”该事件。因此，已成功连接到另一台服务器的通道是处于“connect ready”也就是连接就绪状态。接受传入连接的服务器套接字通道为“accept”也就是已接受就绪状态。已准备好读取数据的通道为“read”，也就是已读取就绪状态。同理，已准备好写入数据为“write”，也就是已准备好写入就绪状态。这四个事件由四个SelectionKey表示：</p>
<ol>
<li>SelectionKey.OP_CONNECT</li>
<li>SelectionKey.OP_ACCEPT</li>
<li>SelectionKey.OP_READ</li>
<li>SelectionKey.OP_WRITE</li>
</ol>
<p>如果想关注多个事件，我们可以将多个常量进行与操作，如下：</p>
<pre><code class="java">int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;
</code></pre>
<h4 id="SelectionKey"><a href="#SelectionKey" class="headerlink" title="SelectionKey"></a>SelectionKey</h4><p>正如上面所看到的，当我们为Selector中注册Channel时，register方法返回一个SelectionKey对象。这个对象包含有如下的属性：</p>
<ul>
<li>Interest Set</li>
<li>ready set</li>
<li>Channel</li>
<li>attached object（可选）</li>
</ul>
<h5 id="Interest-Set"><a href="#Interest-Set" class="headerlink" title="Interest Set"></a>Interest Set</h5><p>Interest Set 是我们关注“选择”的事件集，我们可以通过SelectionKey读取和写入该集，如下：</p>
<pre><code class="java">int interests = selectionKey.interestOps();
boolean isInterestedInAccept = SelectionKey.OP_ACCEPT == (interests &amp; SelectionKey.OP_ACCEPT);
boolean isInterestedInConnect = SelectionKey.OP_CONNECT == (interests &amp; SelectionKey.OP_CONNECT);
boolean isInterestedInRead = SelectionKey.OP_READ == (interests &amp; SelectionKey.OP_READ);
boolean isInterestedInWrite = SelectionKey.OP_write == (insterests &amp; SelectionKey.OP_WRITE);
</code></pre>
<p>向上面这样，我们可以通过与操作来确定某个事件是否在我们的interest set中</p>
<h5 id="Ready-Set"><a href="#Ready-Set" class="headerlink" title="Ready Set"></a>Ready Set</h5><p>ready set 也可以理解为就绪集，是通道准备好的操作集。选择（Selection）后，我们将主要访问ready set。Selection会在稍后介绍。</p>
<pre><code class="java">int readySet = selectionKey.readyOps();
</code></pre>
<p>这里我们可以使用与interest set相同测试方法来检测通道准备好那些事件或操作。但是，我们也可以改用下面这四种方式来检测，它们同样返回的是boolean类型的值。</p>
<pre><code class="java">selectionKey.isAcceptable();
selectionKey.isConnectable();
selectionKey.isReadable();
selectionKey.isWritable();
</code></pre>
<h5 id="channel-Selector"><a href="#channel-Selector" class="headerlink" title="channel+Selector"></a>channel+Selector</h5><p>从SelectionKey中访问channel+selector如下：</p>
<pre><code class="java">Channel channel = selectionKey.channel();
Selector selector = selectionKey.selector();
</code></pre>
<h5 id="Attaching-Objects"><a href="#Attaching-Objects" class="headerlink" title="Attaching Objects"></a>Attaching Objects</h5><p>我们可以将对象附加到SelectionKey，这是识别给定Channel或将更多信息附加到Channel的便捷方式。例如：我们可以将正在使用的Buffer附加到通道中，或者附加一个包含更多聚合数据的对象。如下：</p>
<pre><code class="java">selectionKey.attach(theObject);
Object attachedObj = selectionKey.attachment();
</code></pre>
<p>我们还可以在注册channel时附加对象，如下：</p>
<pre><code class="java">SelectionKey key = channel.register(selector, SelectionKey_OP_READ, theObject);
</code></pre>
<h4 id="通过选择器选择Channel"><a href="#通过选择器选择Channel" class="headerlink" title="通过选择器选择Channel"></a>通过选择器选择Channel</h4><p>一旦我们注册了一个和多个channel到Selector中，我们可以调用其中之一select()方法.,这些方法返回我们关注的事件中已经准备好的通道（connect、accept、read 或 write），也就是如果我们对准备好读取的Channel感兴趣，我们可以从select()方法中收到准备好读取的Channel。</p>
<ul>
<li>int select();</li>
<li>int select(long timeout);</li>
<li>int selectNow();</li>
</ul>
<p><strong>select()</strong>:会阻塞，直到至少有一个通道为注册的事件做好准备。</p>
<p><strong>select(long timeout)</strong>:它的作用于select()相同，只是它设置了最长阻塞时间(单位：ms)。</p>
<p><strong>selectNow()</strong>:它不会阻塞，会立即返回任何准备好的通道。</p>
<p>select方法返回的int值表示有多少通道准备就绪。也就是，自上次调用select以来，准备就绪的通道数量。例如，如果你调用select()并且它返回1，因为一个通道准备就绪，你再次调用select()并且还还有一个通道已经准备好，那么它会再次返回1.</p>
<h5 id="selectedKeys"><a href="#selectedKeys" class="headerlink" title="selectedKeys()"></a>selectedKeys()</h5><p>一旦调用了select方法后，并且返回值表明有一个或多个通道准备好，那么就可以调用选择器selectedKeys()方法，通过“selected key set”访问就绪通道，如下：</p>
<pre><code class="java">Set&lt;SelectionKey&gt; selectKeys = selector.selectedKyes();
Iterator&lt;SelectionKey&gt; keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext())&#123;
    SelectionKey key = keyIterator.next();
    if(key.isAcceptable())&#123;
        //一个连接被一个ServerSocketChannel接受
    &#125;else if(key.isConnectable())&#123;
        //已与远程服务器建立连接
    &#125;else if(key.isReadable())&#123;
        //Channel已经准备好读取
    &#125;else if(key.isWritable())&#123;
        //Channel已经准备好写入
    &#125;
    keyIterator.remove();
&#125;
</code></pre>
<p>上面的程序中会循环所选键集中的键，对于每个键，它会测试该键以确定改建所引用的通道准备好什么事件。注意调用keyIterator.remove()方法，Selector不会从所选键集本身中删除SelectionKey实例。当我们处理完Channel后必须这样做。下次通道变为就绪时，选择器将再次将其添加到选定键集中。</p>
<p>SelectionKey.channel()方法返回的通道应该转换为对应需要使用的Channel，例如，ServerSocketChannel或SocketChannel等。</p>
<h5 id="wakeUp"><a href="#wakeUp" class="headerlink" title="wakeUp()"></a>wakeUp()</h5><p>调用了被阻塞的select()方法的线程可以离开select()方法，及时没有通道准备好。这是通过让不同线程在第一个线程调用select()的selector上调用Selector.wakeUp()方法来完成的。然后在select()方法中等待的线程将立即返回。</p>
<p>如果另外一个线程调用了wakeup()方法，而select()中当前没有线程被阻塞，那么下一个调用select()的线程将立即唤醒。</p>
<h5 id="close"><a href="#close" class="headerlink" title="close()"></a>close()</h5><p>当完成Selector后，将调用其close()方法，这将关闭Selector并是所有注册到此Selector的SelectionKey实例无效。通道本身并未关闭。</p>
<h5 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h5><p>这个例子它打开了一个选择器，用它注册了一个通道（通道实例化部分省略），并持续监视选择器以了解四个事件的准备情况。</p>
<pre><code class="java">Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
while(true) &#123;
  int readyChannels = selector.selectNow();
  if(readyChannels == 0) continue;
  Set&lt;SelectionKey&gt; selectedKeys = selector.selectedKeys();
  Iterator&lt;SelectionKey&gt; keyIterator = selectedKeys.iterator();
  while(keyIterator.hasNext()) &#123;
    SelectionKey key = keyIterator.next();
    if(key.isAcceptable()) &#123;
        // a connection was accepted by a ServerSocketChannel.
    &#125; else if (key.isConnectable()) &#123;
        // a connection was established with a remote server.
    &#125; else if (key.isReadable()) &#123;
        // a channel is ready for reading
    &#125; else if (key.isWritable()) &#123;
        // a channel is ready for writing
    &#125;
    keyIterator.remove();
  &#125;
&#125;
</code></pre>

        </div>

    </div>

    

    

    

    
<div class="article-copyright hairline">
  <p>
    本作品采用 <a rel="license noopener" target="_blank" href="http://creativecommons.org/licenses/by-nc-nd/4.0/">知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议</a> 进行许可。
  </p>
</div>


    

    
<nav class="article-nav">
  
    <a href="/2021/10/30/Java%20NIO-5/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          Java NIO 笔记05
        
      </div>
    </a>
  
  
    <a href="/2021/10/17/Java%20NIO-3/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">Java NIO 笔记03</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <!--<a class="share-item" target="_blank"
            href="https://twitter.com/share?text=Java NIO 笔记04 - Huhailong&url=https://hlovez.gitee.io/2021/10/25/Java%20NIO-4/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>-->
        <a class="share-item" target="_blank"
            href="https://www.douban.com/share/service?name=Java NIO 笔记04 - Huhailong&url=https://hlovez.gitee.io/2021/10/25/Java%20NIO-4/">
            <div class='fa fa-link' type='logo' ></div>
        </a>
        <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=Java NIO 笔记04 - Huhailong&url=https://hlovez.gitee.io/2021/10/25/Java%20NIO-4/&pic=">
            <div class="fa fa-weibo"></i></div>
        </a>
    </section>

</article>






<section class="comments">
    <div id="gitalk-container"></div>
</section>





</div>
                </section>
            </section>

            
            <aside class="sidebar sidebar-search-fix">
                

    <div class="search">
    <div class="has-icon-right">
        <input type="text" class="form-input" id="search" placeholder="SEARCH" autocomplete="off">
        <div class="form-icon">
            <box-icon name='search' color="#3c4859"></box-icon>
        </div>
    </div>
    <div class="search-result" id="search-ps"></div>
</div>


<div class="widget" id="widget">
    
      
  <div class="widget-wrap">
    <div class="widget-inner">
      <div class="toc post-toc-html"></div>
    </div>
  </div>

    
      

    
      
  <div class="widget-wrap widget-tags">
    <div class="widget-title"><span>Tags</span></div>
    <div class="widget-inner">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Java-NIO/" rel="tag">Java NIO</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/java-NIO/" rel="tag">java NIO</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/redis/" rel="tag">redis</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/shiro/" rel="tag">shiro</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/springboot/" rel="tag">springboot</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%AE%89%E5%85%A8/" rel="tag">安全</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%B6%88%E6%81%AF/" rel="tag">消息</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%AC%94%E8%AE%B0/" rel="tag">笔记</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%9A%8F%E7%AC%94/" rel="tag">随笔</a></li></ul>
    </div>
  </div>


    
      
  <div class="widget-wrap widget-recent-posts">
    <div class="widget-title"><span>Recent Posts</span></div>
    <div class="widget-inner">
      <ul>
        
          <li>
            <a href="/2021/10/30/Java%20NIO-5/">Java NIO 笔记05</a>
          </li>
        
          <li>
            <a href="/2021/10/25/Java%20NIO-4/">Java NIO 笔记04</a>
          </li>
        
          <li>
            <a href="/2021/10/17/Java%20NIO-3/">Java NIO 笔记03</a>
          </li>
        
          <li>
            <a href="/2021/10/12/%E6%88%91%E7%9A%84%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%8F%90%E9%80%9F%E5%95%A6/">我的服务器提速啦！</a>
          </li>
        
          <li>
            <a href="/2021/10/10/Java%20NIO2/">Java NIO 笔记02</a>
          </li>
        
      </ul>
    </div>
  </div>

    
      
  <div class="widget-wrap widget-archive">
    <div class="widget-title"><span>Archive</span></div>
    <div class="widget-inner">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2021/">2021</a></li></ul>
    </div>
  </div>


    
</div>

<div id="backtop"><i class="icon icon-arrow-up"></i></div>
            </aside>
            
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            Huhailong &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori </a>
            
            🧡 <span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span>次
</span><span id="busuanzi_container_site_uv">本站访客数<span id="busuanzi_value_site_uv"></span>人次</span>
            
        </div>
    </div>

</footer>


<script src="https://unpkg.com/gitalk/dist/gitalk.min.js"></script>





<script src="/dist/build.js?1630473019367.js"></script>


<script src="/dist/custom.js?1630473019367.js"></script>



<!-- 百度链接提交 -->
<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        }
        else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>




    <script src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>


<!-- Baidu Analytics-->
<script type="text/javascript">
    var _hmt = _hmt || [];
    (function () {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?c15cbbf786572a8cb10802fa47753bb5";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>



</body>

</html>